﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;

namespace ParticleFiltersDemo1
{
    public class ParticleSetTemplatedControl : Control
    {
        private int blockSize = 50;
        private int canvasXOffset = 10;
        private int canvasYOffset = 10;

        private Canvas plotArea;
        private bool isControllInitialized = false;

        public static readonly DependencyProperty ParticlesProperty =
            DependencyProperty.Register( "Particles", typeof( ParticlesSet ), typeof( ParticleSetTemplatedControl ),
            new PropertyMetadata( null, new PropertyChangedCallback( OnParticlesPropertyChanged ) ) );

        public ParticlesSet Particles
        {
            get { return ( ParticlesSet )GetValue( ParticlesProperty ); }
            set { SetValue( ParticlesProperty, value ); }
        }

        public ParticleSetTemplatedControl()
        {
            this.DefaultStyleKey = typeof( ParticleSetTemplatedControl );
        }

        public void PositionChanged()
        {
            // this.SetValue( Canvas.TopProperty, ( object )( ( this.Partickle.Y ) * stepSize + 15 ) );
            // this.SetValue( Canvas.LeftProperty, ( object )( ( this.Partickle.X ) * stepSize + 15 ) );
        }

        public override void OnApplyTemplate()
        {
            this.isControllInitialized = true;
            base.OnApplyTemplate();

            Canvas parentCanvas = this.Parent as Canvas;
            Debug.Assert( parentCanvas != null );

            this.plotArea = this.GetTemplateChild( "plotArea" ) as Canvas;
            
            if ( this.Particles != null )
                this.DrawParticles();
        }

        private void DrawParticles()
        {
            this.plotArea.Children.Clear();
            foreach ( Particle particle in this.Particles.Particles )
            {
                this.DrawSingleParticle( particle.X, particle.Y, particle.heading * Math.PI / 180 );
            }
        }

        private void DrawSingleParticle( double x, double y, double orientation )
        {
            Polygon triangle = new Polygon()
            {
                Fill = new SolidColorBrush( Colors.White ),
                Stroke = new SolidColorBrush( Colors.Green )
            };

            double xFractions = ( x * 10 ) % 10;
            if ( xFractions > 0 )
                xFractions = xFractions / 10;

            double yFractions = ( y * 10 ) % 10;
            if ( yFractions > 0 )
                yFractions = yFractions / 10;

            double xOffset = ( int )x * this.blockSize + canvasXOffset;
            double yOffset = ( int )y * this.blockSize + canvasYOffset;

            double topX = 6;
            double leftX = 0;
            double rightX = 12;

            double topY = 0;
            double leftY = 15;
            double rightY = 15;

            if ( Math.Round( Math.Sin( orientation ) ) == 0 && Math.Round( Math.Cos( orientation ) ) == 1 ) // DOWN
            {
                xOffset += xFractions * 38;
                yOffset += yFractions * 35;

                topY = 15;
                leftY = 0;
                rightY = 0;
            }
            else if ( Math.Round( Math.Sin( orientation ) ) == 1 && Math.Round( Math.Cos( orientation ) ) == 0 ) // RIGHT
            {
                xOffset += xFractions * 35;
                yOffset += yFractions * 38;

                topX = 15; topY = 6;
                leftX = 0; leftY = 0;
                rightX = 0; rightY = 12;
            }
            else if ( Math.Round( Math.Sin( orientation ) ) == -1 && Math.Round( Math.Cos( orientation ) ) == 0 ) // LEFT
            {
                xOffset += xFractions * 35;
                yOffset += yFractions * 38;

                topX = 0; topY = 6;
                leftX = 15; leftY = 0;
                rightX = 15; rightY = 12;
            }
            else
            {
                xOffset += xFractions * 38;
                yOffset += yFractions * 35;
            }
            
            triangle.Points.Add( new Point( topX + xOffset, topY + yOffset ) );
            triangle.Points.Add( new Point( leftX + xOffset, leftY + yOffset ) );
            triangle.Points.Add( new Point( rightX + xOffset, rightY + yOffset ) );

            this.plotArea.Children.Add( triangle );
        }

        private static void OnParticlesPropertyChanged( DependencyObject target, DependencyPropertyChangedEventArgs eh )
        {
            ParticleSetTemplatedControl control = target as ParticleSetTemplatedControl;
            if ( control.isControllInitialized == true && control != null && control.Particles != null )
            {
                control.DrawParticles();
            }
        }
    }
}
